﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WS.EKA.Business.Model;
using WS.EKA.Business.Dal;
using SuperWebSocket;
using WS.EKA.Utility;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;

namespace WS.EKA.UI.Business
{
    public abstract class ClientDataSourceBridge
    {

        public static void Push(WebSocketClientType clientType, WebSocketSession session = null)
        {
            switch (clientType)
            {
                #region IT notience
                case WebSocketClientType.ITNotice_OnDuty:
                    PushOnduty(session);
                    break;
                case WebSocketClientType.ITNotice_AnnounceMent:
                    PushAnnounceMent(session);
                    break;
                case WebSocketClientType.ITNotice_LatestImportantTask:
                    PushImportantTask(session);
                    break;
                #endregion
                #region Incident
                case WebSocketClientType.Incident_30DaysDistribute:
                    Push30DaysDistributeIncident(session);
                    break;
                case WebSocketClientType.Incident_30DaysTrend:
                    Push30DaysTrendIncident(session);
                    break;
                case WebSocketClientType.Incident_HistoryNotResolved:
                    PushIncidentHistoryNotResolvedStatstics(session);
                    break;
                case WebSocketClientType.Incident_StaticsByMonth:
                    PushIncidentStatsticsByMonth(session);
                    break;
                case WebSocketClientType.Incident_Important:
                    PushOrdinaryMode_Important(session);
                    break;
                case WebSocketClientType.Incident_Latest:
                    PushOrdinaryMode_Latest(session);
                    break;
                case WebSocketClientType.Incident_TodayIncidentByFault:
                    PushTodayIncidentByFault(session);
                    break;
                case WebSocketClientType.Incident_TodayResolvedPercent:
                    PushTodayIncidentResolvedPercent(session);
                    break;
                case WebSocketClientType.Incident_TodayStatus:
                    PushTodayStatusIncident(session);
                    break;
                #endregion
                #region Event
                case WebSocketClientType.Event_Source:
                    PushEventSourceStatus(session);
                    break;
                case WebSocketClientType.Event_OperationAppStatus:
                    PushOperationAppStatus(session);
                    break;
                case WebSocketClientType.Event_FoundationAppStatus:
                    PushFondationAppStatus(session);
                    break;
                case WebSocketClientType.Event_OfficeAppStatus:
                    PushOfficeAppStatus(session);
                    break;
                case WebSocketClientType.Event_ManageAppStatus:
                    PushManageAppStatus(session);
                    break;
                case WebSocketClientType.Event_AllWarnSourceDistribute:
                    PushEventSourceDistribute(session);
                    break;
                case WebSocketClientType.Event_List:
                    PushEventList(session);
                    break;
                #endregion
                default:
                    Logger.Error("", new NotImplementedException(clientType + "推送相关的逻辑未实现"), "ClientDataSourceBridge.Push");
                    break;
            }
        }

        #region Incident
        public static void PushIncidentOrdinaryMode(string status, string urgency, DateTime Create_Date)
        {
            //<已解决
            //if ("Logged" == status || "Assigned" == status || "Active" == status)
            //{
            //    //优先级：高
            //    //时间区间：24小时
            //    if ("High" == urgency && (DateTime.Now - Create_Date).Hours <= 24)
            //    {
            //        PushOrdinaryMode_Important();
            //        PushOrdinaryMode_Latest();
            //    }
            //    //最新事件
            //    else
            //    {
            //        PushOrdinaryMode_Latest();
            //    }
            //}
        }

        private static void PushOrdinaryMode_Important(WebSocketSession session = null)
        {
            //try
            //{
                int count = int.Parse(ConfigurationManager.AppSettings["IncidentCount"]);
                var data = IncidentAccess.GetImportantIncidentByCondition(count, 0);
                Push<List<TB_INCIDENT_TEMP>>(WebSocketClientType.Incident_Important, data, session);
            //}
            //catch(Exception ex)
            //{
            //    Logger.Error("重大事件工单推送失败",ex);
            //}

            //var state = new Parameter()
            //{
            //    pageIndex = 0,
            //    PageCount = int.Parse(ConfigurationManager.AppSettings["PageCount"]),
            //    Action = (count, index) =>
            //    {
            //        if (!session.Connected)
            //        {
            //            return Tuple.Create<int, bool>(0, true);
            //        }
            //        var data = IncidentAccess.GetImportantIncidentByCondition(count, index);
            //        Push<List<TB_INCIDENT_TEMP>>(WebSocketClientType.Incident_Important, data, session);
            //        return Tuple.Create<int, bool>(data.Count, false);
            //    },
            //    MillSeconds = int.Parse(ConfigurationManager.AppSettings["MillSeconds"])
            //};
            //Timer t1 = new Timer(PushDataByPage, state, TimeSpan.Zero, new TimeSpan(0, 0,
            //    int.Parse(ConfigurationManager.AppSettings["RefreshMillSeconds"])));
            //state.Instance = t1;
        }

        private static void PushOrdinaryMode_Latest(WebSocketSession session = null)
        {
            int count = int.Parse(ConfigurationManager.AppSettings["IncidentCount"]);
            var data = IncidentAccess.GetLatestIncidentByCondition(count, 0);
            Push<List<TB_INCIDENT_TEMP>>(WebSocketClientType.Incident_Latest, data, session);

            //var state = new Parameter()
            //{
            //    pageIndex = 0,
            //    PageCount = int.Parse(ConfigurationManager.AppSettings["PageCount"]),
            //    Action = (count, index) =>
            //    {
            //        if (!session.Connected)
            //        {
            //            return Tuple.Create<int, bool>(0, true);
            //        }
            //        var data = IncidentAccess.GetLatestIncidentByCondition(count, index);
            //        Push<List<TB_INCIDENT_TEMP>>(WebSocketClientType.Incident_Latest, data, session);
            //        return Tuple.Create<int, bool>(data.Count, false);
            //    },
            //    MillSeconds = int.Parse(ConfigurationManager.AppSettings["MillSeconds"])
            //};
            //Timer t1 = new Timer(PushDataByPage, state, TimeSpan.Zero, new TimeSpan(0, 0,
            //    int.Parse(ConfigurationManager.AppSettings["RefreshMillSeconds"])));
            //state.Instance = t1;
        }


        public static void PushIncidentLeaderMode()
        {
            //重要工单
            PushOrdinaryMode_Important();
            //最近工单
            PushOrdinaryMode_Latest();
            //历史未解决
            PushIncidentHistoryNotResolvedStatstics();
            PushIncidentStatsticsByMonth();
            //今日工单状态
            PushTodayStatusIncident();
            //今日事件工单按故障类型（大类）
            PushTodayIncidentByFault();
            //今日工单解决率
            PushTodayIncidentResolvedPercent();
            // 30天内事件数量走势图
            Push30DaysTrendIncident();
            //30天内事件工单数量按故障分布
            Push30DaysDistributeIncident();
        }

        #region 
        private static void PushIncidentHistoryNotResolvedStatstics(WebSocketSession session = null)
        {
            var data = IncidentAccess.GetIncidentHistoryNotResolvedStatstics();
            Push<IncidentStatisticsModel>(WebSocketClientType.Incident_HistoryNotResolved, data, session);
        }

        private static void PushIncidentStatsticsByMonth(WebSocketSession session = null)
        {
            var data = IncidentAccess.GetIncidentStatsticsByMonth();
            Push<IncidentStatisticsModel>(WebSocketClientType.Incident_StaticsByMonth, data, session);
        }

        private static void PushTodayStatusIncident(WebSocketSession session = null)
        {
            List<TodayStatusIncidentForUI> data = IncidentAccess.GetTodayStatusIncident();
            Push<List<TodayStatusIncidentForUI>>(WebSocketClientType.Incident_TodayStatus, data, session);
        }
        private static void PushTodayIncidentByFault(WebSocketSession session = null)
        {
            List<TodayIncidentByFaultForUI> data = IncidentAccess.GetTodayIncidentByFault();
            Push<List<TodayIncidentByFaultForUI>>(WebSocketClientType.Incident_TodayIncidentByFault, data, session);
        }
        private static void PushTodayIncidentResolvedPercent(WebSocketSession session = null)
        {
            TodayIncidentResolvedPercentForUI data = IncidentAccess.GetTodayIncidentResolvedPercent();
            Push<TodayIncidentResolvedPercentForUI>(WebSocketClientType.Incident_TodayResolvedPercent, data, session);
        }
        private static void Push30DaysTrendIncident(WebSocketSession session = null)
        {
            List<_30DaysTrendForUI> data = IncidentAccess.Get30DaysTrendIncident();
            Push<List<_30DaysTrendForUI>>(WebSocketClientType.Incident_30DaysTrend, data, session);
        }
        private static void Push30DaysDistributeIncident(WebSocketSession session = null)
        {
            List<_30DaysDistributeForUI> data = IncidentAccess.Get30DaysDistributeIncident();
            Push<List<_30DaysDistributeForUI>>(WebSocketClientType.Incident_30DaysDistribute, data, session);
        }
        #endregion
        #endregion

        #region IT notience
        private static void PushOnduty(WebSocketSession session = null)
        {
            List<OnDuty> onDuty = ITAnnouncementAccess.GetLatestOnDuty();
            Push<List<OnDuty>>(WebSocketClientType.ITNotice_OnDuty, onDuty, session);
        }

        private static void PushImportantTask(WebSocketSession session = null)
        {
            List<LatestImportantTask> task = ITAnnouncementAccess.GetLatestImportantTask(1);
            Push<List<LatestImportantTask>>(WebSocketClientType.ITNotice_LatestImportantTask, task, session);
        }

        private static void PushAnnounceMent(WebSocketSession session = null)
        {
            List<AnnounceMent> task = ITAnnouncementAccess.GetAnnounceMent(1);
            Push<List<AnnounceMent>>(WebSocketClientType.ITNotice_AnnounceMent, task, session);
        }
        #endregion

        #region Event

        /// <summary>
        /// 事件接口接收到数据时立即调用
        /// </summary>
        public static void PushEventToClient()
        {
            PushEventSourceStatus();
            PushOperationAppStatus();
            PushFondationAppStatus();
            PushOfficeAppStatus();
            PushManageAppStatus();
            PushEventSourceDistribute();
            PushEventList();
        }

        private static void PushEventList(WebSocketSession session = null)
        {
            var sources = EventAccess.GetEventList();
            Push<EventListForUI>(WebSocketClientType.Event_List, sources, session);
        }

        private static void PushEventSourceStatus(WebSocketSession session = null)
        {
            var sources = EventAccess.GetEventSourceWarnProportion();
            Push<List<EventSourceForUI>>(WebSocketClientType.Event_Source, sources, session);
        }

        private static void PushOperationAppStatus(WebSocketSession session = null)
        {
            var sources = EventAccess.GetOperationAppStatus();
            Push<List<AppStatus>>(WebSocketClientType.Event_OperationAppStatus, sources, session);
        }

        private static void PushFondationAppStatus(WebSocketSession session = null)
        {
            var sources = EventAccess.GetFondationAppStatus();
            Push<List<AppStatus>>(WebSocketClientType.Event_FoundationAppStatus, sources, session);
        }

        private static void PushOfficeAppStatus(WebSocketSession session = null)
        {
            var sources = EventAccess.GetOfficeAppStatus();
            Push<List<AppStatus>>(WebSocketClientType.Event_OfficeAppStatus, sources, session);
        }

        private static void PushManageAppStatus(WebSocketSession session = null)
        {
            var sources = EventAccess.GetManageAppStatus();
            Push<List<AppStatus>>(WebSocketClientType.Event_ManageAppStatus, sources, session);
        }

        private static void PushEventSourceDistribute(WebSocketSession session = null)
        {
            var sources = EventAccess.GetEventSourceDistribute();
            Push<List<EventSourcePie>>(WebSocketClientType.Event_AllWarnSourceDistribute, sources, session);
        }

        #endregion

        #region common
        private static void Push<T>(WebSocketClientType type, T model, WebSocketSession session = null)
        {
            if (session != null)
            {
                string json = ReportFactory.GetReportFactory(type).GetJsonString(new ReportParameter<T>() { Data = model });
                session.Send(json);
                return;
            }
            MessagePublisher.Instance.Push<T>(model, type);
        }

        private static void PushDataByPage(object state)
        {
            var obj = state as Parameter;
            if (obj.TokenSource != null)
            {
                obj.TokenSource.Cancel();
            }
            var tokenSource = new CancellationTokenSource();
            obj.TokenSource = tokenSource;
            Task.Factory.StartNew(() =>
            {
                while (!tokenSource.Token.IsCancellationRequested)
                {
                    var ret = obj.Action(obj.PageCount, obj.pageIndex);
                    //到组后一页循环显示
                    if (ret.Item1 < obj.PageCount)
                        obj.pageIndex = 0;
                    obj.pageIndex++;
                    //close timer task
                    if (ret.Item2)
                    {
                        obj.Instance.Dispose();
                        break;
                    }
                    Thread.Sleep(obj.MillSeconds);
                }

            }, tokenSource.Token);
        }

        #endregion
    }

    class Parameter
    {
        public int PageCount { get; set; }
        public int pageIndex { get; set; }
        public CancellationTokenSource TokenSource { get; set; }
        public Func<int, int, Tuple<int, bool>> Action { get; set; }
        //煤业数据切换的间隔时间
        public int MillSeconds { get; set; }
        public bool ScheduleTaskCancelled { get; set; }
        public Timer Instance { get; set; }
    }
}
